package com.iring.service.common.impl;

import javax.transaction.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.iring.domain.config.PayConfig;
import com.iring.domain.config.prop.LocalConfigProperties;
import com.iring.domain.config.prop.VOSCustomerProperties;
import com.iring.dao.common.PayOrderDao;
import com.iring.dao.vos.PayReturnDao;
import com.iring.domain.common.AmountTask;
import com.iring.domain.common.PayOrder;
import com.iring.domain.common.User;
import com.iring.domain.config.PayStatusEnum;
import com.iring.domain.vos.pay.PayReturn;
import com.iring.domain.vos.pay.VosPay;
import com.iring.exception.ParamInvalidException;
import com.iring.exception.config.ErrorEnum;
import com.iring.service.common.OrderService;
import com.iring.service.common.PayAmountService;
import com.iring.service.common.UserService;

/**
 * @author wanggan
 */
@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    PayOrderDao orderDao;

    @Autowired
    PayAmountService payAmountService;

    @Autowired
    UserService userService;

    @Autowired
    LocalConfigProperties localUserProperties;

    @Autowired
    VOSCustomerProperties vosCustomerProperties;

    @Autowired
    PayReturnDao payDao;

    @Override
    public PayOrder updateOrderStatus(String tradeNo, String payStatus, String payerid) {
        PayOrder payOrder = orderDao.findByTradeNo(tradeNo);
        payOrder.setPayStatus(payStatus);
        payOrder.setOrderStatus(PayStatusEnum.SYSTEM_PROCESSING.getValue());
        payOrder.setPayerId(payerid);
        payOrder.setOrderPayTime(null);
        return orderDao.save(payOrder);
    }

    @Override
    public Boolean cancelOrder(String tradeNo,Boolean fromUser) {
        //取消订单
        PayOrder payOrder = orderDao.findByTradeNo(tradeNo);
        payOrder.setOrderCloseTime(null);
        payOrder.setPayStatus(PayConfig.ORDER_FAILED);
        payOrder.setOrderStatus(PayStatusEnum.PAY_CLOSED.getValue());
        orderDao.save(payOrder);
        return Boolean.TRUE;
    }



    @Override
    public PayOrder save(PayOrder payOrder) {
        return orderDao.save(payOrder);
    }

    @Transactional
    @Override
    public User updateByOrderid(String orderid, String tradeNo, String payStatus, String payerid) {
        //先对vos进行充值，成功才进行本地更新
        // 获取订单信息
        //优先进行保存支付信息，再来处理其他的
        PayOrder payOrder = orderDao.findByOrderId(orderid);
        synchronized (payOrder.getOrderStatus()) {
            payOrder.setOrderStatus(PayStatusEnum.SYSTEM_PROCESSING.getValue());
            payOrder.setPayStatus(payStatus);
            payOrder.setTradeNo(tradeNo);
            payOrder.setPayerId(payerid);
            payOrder.setOrderPayTime(null);
            payOrder = orderDao.save(payOrder);
            Boolean ispay = vosTopup(orderid);
            if(!ispay){
                // 如果没有成功,循环五次,直到充值成功
                Boolean isokay = false;
                for (int i = 0; i < 5; i++) {
                    ispay = vosTopup(orderid);
                    if (ispay) {
                        isokay = true;
                        break;
                    }
                }
                if (!isokay) {

                    // 如果5次后依然没有成功,未完成充值,添加到任务列表
                    AmountTask task = new AmountTask();
                    task.setOptamounts(payOrder.getOptAmounts());
                    task.setOrderid(payOrder.getOrderId());
                    task.setUsername(payOrder.getUsername());
                    payAmountService.createTask(task);
                }
            }
        }
        return userService.getUserByUsername(payOrder.getUsername());
    }


    private Boolean vosTopup(String orderid) {
        PayOrder payOrder = orderDao.findByOrderId(orderid);
        VosPay vosPay = new VosPay(payOrder.getUsername(), vosCustomerProperties.getOwnerType(),
                payOrder.getOptAmounts(), "top-up");
        PayReturn payReturn = payDao.createVosPay(vosPay);
        if (payReturn != null) {
            if (payReturn.getInfoPay().getPayMoney()
                    .compareTo(payOrder.getOptAmounts()) == 0) {
                // 如果充值金额等于操作的金额
                // 更新订单的状态
                Integer res = orderDao.updateOrderTrans(orderid, localUserProperties.getPayOpt());
                logger.info("res={}",res);
                if (res == 0) {
                    throw new ParamInvalidException(ErrorEnum.PAY_FAILED);
                } else {
                    logger.info("create local pay success={}",res);
                }
                return Boolean.TRUE;
            } else {
                throw new ParamInvalidException(ErrorEnum.PAY_AMOUNT_DIFF);
            }
        }
        return Boolean.FALSE;
    }
}
